home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / X11R4 / cmds / X / extensions / RCS / shape.c,v < prev   
Encoding:
Text File  |  1991-02-20  |  26.1 KB  |  1,071 lines

  1. head     1.2;
  2. branch   ;
  3. access   ;
  4. symbols  ;
  5. locks    ; strict;
  6. comment  @ * @;
  7.  
  8.  
  9. 1.2
  10. date     91.02.19.21.41.20;  author kupfer;  state Exp;
  11. branches ;
  12. next     1.1;
  13.  
  14. 1.1
  15. date     90.07.11.11.30.25;  author mgbaker;  state Exp;
  16. branches ;
  17. next     ;
  18.  
  19.  
  20. desc
  21. @Initial version
  22. @
  23.  
  24.  
  25. 1.2
  26. log
  27. @Patch #1 from MIT.
  28. @
  29. text
  30. @/************************************************************
  31. Copyright 1989 by The Massachusetts Institute of Technology
  32.  
  33. Permission to use, copy, modify, and distribute this
  34. software and its documentation for any purpose and without
  35. fee is hereby granted, provided that the above copyright
  36. no- tice appear in all copies and that both that copyright
  37. no- tice and this permission notice appear in supporting
  38. docu- mentation, and that the name of MIT not be used in
  39. advertising or publicity pertaining to distribution of the
  40. software without specific prior written permission.
  41. M.I.T. makes no representation about the suitability of
  42. this software for any purpose. It is provided "as is"
  43. without any express or implied warranty.
  44.  
  45. MIT DISCLAIMS ALL WARRANTIES WITH REGARD TO  THIS  SOFTWARE,
  46. INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FIT-
  47. NESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL MIT BE  LI-
  48. ABLE  FOR  ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
  49. ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,  DATA  OR
  50. PROFITS,  WHETHER  IN  AN  ACTION OF CONTRACT, NEGLIGENCE OR
  51. OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION  WITH
  52. THE USE OR PERFORMANCE OF THIS SOFTWARE.
  53.  
  54. ********************************************************/
  55.  
  56. /* $XConsortium: shape.c,v 5.11 90/01/23 10:49:17 rws Exp $ */
  57. #define NEED_REPLIES
  58. #define NEED_EVENTS
  59. #include <stdio.h>
  60. #include "X.h"
  61. #include "Xproto.h"
  62. #include "misc.h"
  63. #include "os.h"
  64. #include "windowstr.h"
  65. #include "scrnintstr.h"
  66. #include "pixmapstr.h"
  67. #include "extnsionst.h"
  68. #include "dixstruct.h"
  69. #include "resource.h"
  70. #include "opaque.h"
  71. #define _SHAPE_SERVER_    /* don't want Xlib structures */
  72. #include "shapestr.h"
  73. #include "regionstr.h"
  74. #include "gcstruct.h"
  75.  
  76. static int ShapeFreeClient(), ShapeFreeEvents();
  77. static void SendShapeNotify();
  78.  
  79. static unsigned char ShapeReqCode = 0;
  80. static int ShapeEventBase = 0;
  81. static RESTYPE ClientType, EventType; /* resource types for event masks */
  82.  
  83. /*
  84.  * each window has a list of clients requesting
  85.  * ShapeNotify events.  Each client has a resource
  86.  * for each window it selects ShapeNotify input for,
  87.  * this resource is used to delete the ShapeNotifyRec
  88.  * entry from the per-window queue.
  89.  */
  90.  
  91. typedef struct _ShapeEvent *ShapeEventPtr;
  92.  
  93. typedef struct _ShapeEvent {
  94.     ShapeEventPtr   next;
  95.     ClientPtr        client;
  96.     WindowPtr        window;
  97.     XID            clientResource;
  98. } ShapeEventRec;
  99.  
  100. /****************
  101.  * ShapeExtensionInit
  102.  *
  103.  * Called from InitExtensions in main() or from QueryExtension() if the
  104.  * extension is dynamically loaded.
  105.  *
  106.  ****************/
  107.  
  108. void
  109. ShapeExtensionInit()
  110. {
  111.     ExtensionEntry *extEntry, *AddExtension();
  112.     static int ProcShapeDispatch(), SProcShapeDispatch();
  113.     static void  ShapeResetProc(), SShapeNotifyEvent();
  114.  
  115.     ClientType = CreateNewResourceType(ShapeFreeClient);
  116.     EventType = CreateNewResourceType(ShapeFreeEvents);
  117.     if (ClientType && EventType &&
  118.     (extEntry = AddExtension(SHAPENAME, ShapeNumberEvents, 0,
  119.                  ProcShapeDispatch, SProcShapeDispatch,
  120.                  ShapeResetProc, StandardMinorOpcode)))
  121.     {
  122.     ShapeReqCode = (unsigned char)extEntry->base;
  123.     ShapeEventBase = extEntry->eventBase;
  124.     EventSwapVector[ShapeEventBase] = SShapeNotifyEvent;
  125.     }
  126. }
  127.  
  128. /*ARGSUSED*/
  129. static void
  130. ShapeResetProc (extEntry)
  131. ExtensionEntry    *extEntry;
  132. {
  133. }
  134.  
  135. static
  136. RegionOperate (client, pWin, kind, destRgnp, srcRgn, op, xoff, yoff, create)
  137.     ClientPtr    client;
  138.     WindowPtr    pWin;
  139.     int        kind;
  140.     RegionPtr    *destRgnp, srcRgn;
  141.     int        op;
  142.     int        xoff, yoff;
  143.     RegionPtr    (*create)();    /* creates a reasonable *destRgnp */
  144. {
  145.     ScreenPtr    pScreen = pWin->drawable.pScreen;
  146.  
  147.     if (srcRgn && (xoff || yoff))
  148.     (*pScreen->TranslateRegion) (srcRgn, xoff, yoff);
  149.     if (!pWin->parent)
  150.     {
  151.     if (srcRgn)
  152.         (*pScreen->RegionDestroy) (srcRgn);
  153.     return Success;
  154.     }
  155.     switch (op) {
  156.     case ShapeSet:
  157.     if (*destRgnp)
  158.         (*pScreen->RegionDestroy) (*destRgnp);
  159.     *destRgnp = srcRgn;
  160.     srcRgn = 0;
  161.     break;
  162.     case ShapeUnion:
  163.     if (*destRgnp)
  164.         (*pScreen->Union) (*destRgnp, *destRgnp, srcRgn);
  165.     break;
  166.     case ShapeIntersect:
  167.     if (*destRgnp)
  168.         (*pScreen->Intersect) (*destRgnp, *destRgnp, srcRgn);
  169.     else {
  170.         *destRgnp = srcRgn;
  171.         srcRgn = 0;
  172.     }
  173.     break;
  174.     case ShapeSubtract:
  175.     if (!*destRgnp)
  176.         *destRgnp = (*create)(pWin);
  177.     (*pScreen->Subtract) (*destRgnp, *destRgnp, srcRgn);
  178.     break;
  179.     case ShapeInvert:
  180.     if (!*destRgnp)
  181.         *destRgnp = (*pScreen->RegionCreate) ((BoxPtr) 0, 0);
  182.     else
  183.         (*pScreen->Subtract) (*destRgnp, srcRgn, *destRgnp);
  184.     break;
  185.     default:
  186.     client->errorValue = op;
  187.     return BadValue;
  188.     }
  189.     if (srcRgn)
  190.     (*pScreen->RegionDestroy) (srcRgn);
  191.     SetShape (pWin);
  192.     SendShapeNotify (pWin, kind);
  193.     return Success;
  194. }
  195.  
  196. static RegionPtr
  197. CreateBoundingShape (pWin)
  198.     WindowPtr    pWin;
  199. {
  200.     BoxRec    extents;
  201.  
  202.     extents.x1 = -wBorderWidth (pWin);
  203.     extents.y1 = -wBorderWidth (pWin);
  204.     extents.x2 = pWin->drawable.width + wBorderWidth (pWin);
  205.     extents.y2 = pWin->drawable.height + wBorderWidth (pWin);
  206.     return (*pWin->drawable.pScreen->RegionCreate) (&extents, 1);
  207. }
  208.  
  209. static RegionPtr
  210. CreateClipShape (pWin)
  211.     WindowPtr    pWin;
  212. {
  213.     BoxRec    extents;
  214.  
  215.     extents.x1 = 0;
  216.     extents.y1 = 0;
  217.     extents.x2 = pWin->drawable.width;
  218.     extents.y2 = pWin->drawable.height;
  219.     return (*pWin->drawable.pScreen->RegionCreate) (&extents, 1);
  220. }
  221.  
  222. static int
  223. ProcShapeQueryVersion (client)
  224.     register ClientPtr    client;
  225. {
  226.     REQUEST(xShapeQueryVersionReq);
  227.     xShapeQueryVersionReply    rep;
  228.     register int        n;
  229.  
  230.     REQUEST_SIZE_MATCH (xShapeQueryVersionReq);
  231.     rep.type = X_Reply;
  232.     rep.length = 0;
  233.     rep.sequenceNumber = client->sequence;
  234.     rep.majorVersion = SHAPE_MAJOR_VERSION;
  235.     rep.minorVersion = SHAPE_MINOR_VERSION;
  236.     if (client->swapped) {
  237.         swaps(&rep.sequenceNumber, n);
  238.         swapl(&rep.length, n);
  239.     swaps(&rep.majorVersion, n);
  240.     swaps(&rep.minorVersion, n);
  241.     }
  242.     WriteToClient(client, sizeof (xShapeQueryVersionReply), (char *)&rep);
  243.     return (client->noClientException);
  244. }
  245.  
  246. /*****************
  247.  * ProcShapeRectangles
  248.  *
  249.  *****************/
  250.  
  251. static int
  252. ProcShapeRectangles (client)
  253.     register ClientPtr client;
  254. {
  255.     WindowPtr        pWin;
  256.     ScreenPtr        pScreen;
  257.     REQUEST(xShapeRectanglesReq);
  258.     xRectangle        *prects;
  259.     int                nrects, ctype;
  260.     RegionPtr        srcRgn;
  261.     RegionPtr        *destRgn;
  262.     RegionPtr        (*createDefault)();
  263.     int            destBounding;
  264.  
  265.     REQUEST_AT_LEAST_SIZE (xShapeRectanglesReq);
  266.     UpdateCurrentTime();
  267.     pWin = LookupWindow (stuff->dest, client);
  268.     if (!pWin)
  269.     return BadWindow;
  270.     switch (stuff->destKind) {
  271.     case ShapeBounding:
  272.     destBounding = 1;
  273.     createDefault = CreateBoundingShape;
  274.     break;
  275.     case ShapeClip:
  276.     destBounding = 0;
  277.     createDefault = CreateClipShape;
  278.     break;
  279.     default:
  280.     client->errorValue = stuff->destKind;
  281.     return BadValue;
  282.     }
  283.     if ((stuff->ordering != Unsorted) && (stuff->ordering != YSorted) &&
  284.     (stuff->ordering != YXSorted) && (stuff->ordering != YXBanded))
  285.     {
  286.     client->errorValue = stuff->ordering;
  287.         return BadValue;
  288.     }
  289.     pScreen = pWin->drawable.pScreen;
  290.     nrects = ((stuff->length  << 2) - sizeof(xShapeRectanglesReq));
  291.     if (nrects & 4)
  292.     return BadLength;
  293.     nrects >>= 3;
  294.     prects = (xRectangle *) &stuff[1];
  295.     ctype = VerifyRectOrder(nrects, prects, (int)stuff->ordering);
  296.     if (ctype < 0)
  297.     return BadMatch;
  298.     srcRgn = (*pScreen->RectsToRegion)(nrects, prects, ctype);
  299.  
  300.     if (!pWin->optional)
  301.     MakeWindowOptional (pWin);
  302.     if (destBounding)
  303.     destRgn = &pWin->optional->boundingShape;
  304.     else
  305.     destRgn = &pWin->optional->clipShape;
  306.  
  307.     return RegionOperate (client, pWin, (int)stuff->destKind,
  308.               destRgn, srcRgn, (int)stuff->op,
  309.               stuff->xOff, stuff->yOff, createDefault);
  310. }
  311.  
  312. /**************
  313.  * ProcShapeMask
  314.  **************/
  315.  
  316. static int
  317. ProcShapeMask (client)
  318.     register ClientPtr client;
  319. {
  320.     WindowPtr        pWin;
  321.     ScreenPtr        pScreen;
  322.     REQUEST(xShapeMaskReq);
  323.     RegionPtr        srcRgn;
  324.     RegionPtr        *destRgn;
  325.     PixmapPtr        pPixmap;
  326.     RegionPtr        (*createDefault)();
  327.     int            destBounding;
  328.  
  329.     REQUEST_SIZE_MATCH (xShapeMaskReq);
  330.     UpdateCurrentTime();
  331.     pWin = LookupWindow (stuff->dest, client);
  332.     if (!pWin)
  333.     return BadWindow;
  334.     switch (stuff->destKind) {
  335.     case ShapeBounding:
  336.     destBounding = 1;
  337.     createDefault = CreateBoundingShape;
  338.     break;
  339.     case ShapeClip:
  340.     destBounding = 0;
  341.     createDefault = CreateClipShape;
  342.     break;
  343.     default:
  344.     client->errorValue = stuff->destKind;
  345.     return BadValue;
  346.     }
  347.     pScreen = pWin->drawable.pScreen;
  348.     if (stuff->src == None)
  349.     srcRgn = 0;
  350.     else {
  351.         pPixmap = (PixmapPtr) LookupIDByType(stuff->src, RT_PIXMAP);
  352.         if (!pPixmap)
  353.         return BadPixmap;
  354.     if (pPixmap->drawable.pScreen != pScreen)
  355.         return BadMatch;
  356.     srcRgn = (*pScreen->BitmapToRegion)(pPixmap);
  357.     }
  358.  
  359.     if (!pWin->optional)
  360.     MakeWindowOptional (pWin);
  361.     if (destBounding)
  362.     destRgn = &pWin->optional->boundingShape;
  363.     else
  364.     destRgn = &pWin->optional->clipShape;
  365.  
  366.     return RegionOperate (client, pWin, (int)stuff->destKind,
  367.               destRgn, srcRgn, (int)stuff->op,
  368.               stuff->xOff, stuff->yOff, createDefault);
  369. }
  370.  
  371. /************
  372.  * ProcShapeCombine
  373.  ************/
  374.  
  375. static int
  376. ProcShapeCombine (client)
  377.     register ClientPtr client;
  378. {
  379.     WindowPtr        pSrcWin, pDestWin;
  380.     ScreenPtr        pScreen;
  381.     REQUEST(xShapeCombineReq);
  382.     RegionPtr        srcRgn;
  383.     RegionPtr        *destRgn;
  384.     RegionPtr        (*createDefault)();
  385.     RegionPtr        (*createSrc)();
  386.     RegionPtr        tmp;
  387.     int            destBounding;
  388.  
  389.     REQUEST_SIZE_MATCH (xShapeCombineReq);
  390.     UpdateCurrentTime();
  391.     pDestWin = LookupWindow (stuff->dest, client);
  392.     if (!pDestWin)
  393.     return BadWindow;
  394.     if (!pDestWin->optional)
  395.     MakeWindowOptional (pDestWin);
  396.     switch (stuff->destKind) {
  397.     case ShapeBounding:
  398.     destBounding = 1;
  399.     createDefault = CreateBoundingShape;
  400.     break;
  401.     case ShapeClip:
  402.     destBounding = 0;
  403.     createDefault = CreateClipShape;
  404.     break;
  405.     default:
  406.     client->errorValue = stuff->destKind;
  407.     return BadValue;
  408.     }
  409.     pScreen = pDestWin->drawable.pScreen;
  410.  
  411.     pSrcWin = LookupWindow (stuff->src, client);
  412.     if (!pSrcWin)
  413.     return BadWindow;
  414.     switch (stuff->srcKind) {
  415.     case ShapeBounding:
  416.     srcRgn = wBoundingShape (pSrcWin);
  417.     createSrc = CreateBoundingShape;
  418.     break;
  419.     case ShapeClip:
  420.     srcRgn = wClipShape (pSrcWin);
  421.     createSrc = CreateClipShape;
  422.     break;
  423.     default:
  424.     client->errorValue = stuff->srcKind;
  425.     return BadValue;
  426.     }
  427.     if (pSrcWin->drawable.pScreen != pScreen)
  428.     {
  429.     return BadMatch;
  430.     }
  431.  
  432.     if (srcRgn) {
  433.         tmp = (*pScreen->RegionCreate) ((BoxPtr) 0, 0);
  434.         (*pScreen->RegionCopy) (tmp, srcRgn);
  435.         srcRgn = tmp;
  436.     } else
  437.     srcRgn = (*createSrc) (pSrcWin);
  438.  
  439.     if (!pDestWin->optional)
  440.     MakeWindowOptional (pDestWin);
  441.     if (destBounding)
  442.     destRgn = &pDestWin->optional->boundingShape;
  443.     else
  444.     destRgn = &pDestWin->optional->clipShape;
  445.  
  446.     return RegionOperate (client, pDestWin, (int)stuff->destKind,
  447.               destRgn, srcRgn, (int)stuff->op,
  448.               stuff->xOff, stuff->yOff, createDefault);
  449. }
  450.  
  451. /*************
  452.  * ProcShapeOffset
  453.  *************/
  454.  
  455. static int
  456. ProcShapeOffset (client)
  457.     register ClientPtr client;
  458. {
  459.     WindowPtr        pWin;
  460.     ScreenPtr        pScreen;
  461.     REQUEST(xShapeOffsetReq);
  462.     RegionPtr        srcRgn;
  463.  
  464.     REQUEST_SIZE_MATCH (xShapeOffsetReq);
  465.     UpdateCurrentTime();
  466.     pWin = LookupWindow (stuff->dest, client);
  467.     if (!pWin)
  468.     return BadWindow;
  469.     switch (stuff->destKind) {
  470.     case ShapeBounding:
  471.     srcRgn = wBoundingShape (pWin);
  472.     break;
  473.     case ShapeClip:
  474.     srcRgn = wClipShape(pWin);
  475.     break;
  476.     default:
  477.     client->errorValue = stuff->destKind;
  478.     return BadValue;
  479.     }
  480.     pScreen = pWin->drawable.pScreen;
  481.     if (srcRgn)
  482.     {
  483.         (*pScreen->TranslateRegion) (srcRgn, stuff->xOff, stuff->yOff);
  484.         SetShape (pWin);
  485.     }
  486.     SendShapeNotify (pWin, (int)stuff->destKind);
  487.     return Success;
  488. }
  489.  
  490. static int
  491. ProcShapeQueryExtents (client)
  492.     register ClientPtr    client;
  493. {
  494.     REQUEST(xShapeQueryExtentsReq);
  495.     WindowPtr        pWin;
  496.     xShapeQueryExtentsReply    rep;
  497.     BoxRec        extents;
  498.     register int    n;
  499.  
  500.     REQUEST_SIZE_MATCH (xShapeQueryExtentsReq);
  501.     pWin = LookupWindow (stuff->window, client);
  502.     if (!pWin)
  503.     return BadWindow;
  504.     rep.type = X_Reply;
  505.     rep.length = 0;
  506.     rep.sequenceNumber = client->sequence;
  507.     rep.boundingShaped = (wBoundingShape(pWin) != 0);
  508.     rep.clipShaped = (wClipShape(pWin) != 0);
  509.     if (wBoundingShape(pWin)) {
  510.     extents = *(pWin->drawable.pScreen->RegionExtents) (wBoundingShape(pWin));
  511.     } else {
  512.     extents.x1 = -wBorderWidth (pWin);
  513.     extents.y1 = -wBorderWidth (pWin);
  514.     extents.x2 = pWin->drawable.width + wBorderWidth (pWin);
  515.     extents.y2 = pWin->drawable.height + wBorderWidth (pWin);
  516.     }
  517.     rep.xBoundingShape = extents.x1;
  518.     rep.yBoundingShape = extents.y1;
  519.     rep.widthBoundingShape = extents.x2 - extents.x1;
  520.     rep.heightBoundingShape = extents.y2 - extents.y1;
  521.     if (wClipShape(pWin)) {
  522.     extents = *(pWin->drawable.pScreen->RegionExtents) (wClipShape(pWin));
  523.     } else {
  524.     extents.x1 = 0;
  525.     extents.y1 = 0;
  526.     extents.x2 = pWin->drawable.width;
  527.     extents.y2 = pWin->drawable.height;
  528.     }
  529.     rep.xClipShape = extents.x1;
  530.     rep.yClipShape = extents.y1;
  531.     rep.widthClipShape = extents.x2 - extents.x1;
  532.     rep.heightClipShape = extents.y2 - extents.y1;
  533.     if (client->swapped) {
  534.         swaps(&rep.sequenceNumber, n);
  535.         swapl(&rep.length, n);
  536.     swaps(&rep.xBoundingShape, n);
  537.     swaps(&rep.yBoundingShape, n);
  538.     swaps(&rep.widthBoundingShape, n);
  539.     swaps(&rep.heightBoundingShape, n);
  540.     swaps(&rep.xClipShape, n);
  541.     swaps(&rep.yClipShape, n);
  542.     swaps(&rep.widthClipShape, n);
  543.     swaps(&rep.heightClipShape, n);
  544.     }
  545.     WriteToClient(client, sizeof (xShapeQueryExtentsReply), (char *)&rep);
  546.     return (client->noClientException);
  547. }
  548.  
  549. /*ARGSUSED*/
  550. static int
  551. ShapeFreeClient (data, id)
  552.     pointer        data;
  553.     XID            id;
  554. {
  555.     ShapeEventPtr   pShapeEvent;
  556.     WindowPtr        pWin;
  557.     ShapeEventPtr   *pHead, pCur, pPrev;
  558.  
  559.     pShapeEvent = (ShapeEventPtr) data;
  560.     pWin = pShapeEvent->window;
  561.     pHead = (ShapeEventPtr *) LookupIDByType(pWin->drawable.id, EventType);
  562.     if (pHead) {
  563.     pPrev = 0;
  564.     for (pCur = *pHead; pCur && pCur != pShapeEvent; pCur=pCur->next)
  565.         pPrev = pCur;
  566.     if (pPrev)
  567.         pPrev->next = pShapeEvent->next;
  568.     else
  569.         *pHead = pShapeEvent->next;
  570.     }
  571.     xfree ((pointer) pShapeEvent);
  572. }
  573.  
  574. /*ARGSUSED*/
  575. static int
  576. ShapeFreeEvents (data, id)
  577.     pointer        data;
  578.     XID            id;
  579. {
  580.     ShapeEventPtr   *pHead, pCur, pNext;
  581.  
  582.     pHead = (ShapeEventPtr *) data;
  583.     for (pCur = *pHead; pCur; pCur = pNext) {
  584.     pNext = pCur->next;
  585.     FreeResource (pCur->clientResource, ClientType);
  586.     xfree ((pointer) pCur);
  587.     }
  588.     xfree ((pointer) pHead);
  589. }
  590.  
  591. static int
  592. ProcShapeSelectInput (client)
  593.     register ClientPtr    client;
  594. {
  595.     REQUEST(xShapeSelectInputReq);
  596.     WindowPtr        pWin;
  597.     ShapeEventPtr    pShapeEvent, pNewShapeEvent, *pHead;
  598.     XID            clientResource;
  599.  
  600.     REQUEST_SIZE_MATCH (xShapeSelectInputReq);
  601.     pWin = LookupWindow (stuff->window, client);
  602.     if (!pWin)
  603.     return BadWindow;
  604.     pHead = (ShapeEventPtr *) LookupIDByType(pWin->drawable.id, EventType);
  605.     switch (stuff->enable) {
  606.     case xTrue:
  607.     if (pHead) {
  608.  
  609.         /* check for existing entry. */
  610.         for (pShapeEvent = *pHead;
  611.          pShapeEvent;
  612.           pShapeEvent = pShapeEvent->next)
  613.         {
  614.         if (pShapeEvent->client == client)
  615.             return Success;
  616.         }
  617.     }
  618.  
  619.     /* build the entry */
  620.         pNewShapeEvent = (ShapeEventPtr)
  621.                 xalloc (sizeof (ShapeEventRec));
  622.         if (!pNewShapeEvent)
  623.         return BadAlloc;
  624.         pNewShapeEvent->next = 0;
  625.         pNewShapeEvent->client = client;
  626.         pNewShapeEvent->window = pWin;
  627.         /*
  628.       * add a resource that will be deleted when
  629.           * the client goes away
  630.           */
  631.        clientResource = FakeClientID (client->index);
  632.         pNewShapeEvent->clientResource = clientResource;
  633.         if (!AddResource (clientResource, ClientType, (pointer)pNewShapeEvent))
  634.         {
  635.         xfree (pNewShapeEvent);
  636.         return BadAlloc;
  637.         }
  638.         /*
  639.           * create a resource to contain a pointer to the list
  640.           * of clients selecting input.  This must be indirect as
  641.           * the list may be arbitrarily rearranged which cannot be
  642.           * done through the resource database.
  643.           */
  644.         if (!pHead)
  645.         {
  646.         pHead = (ShapeEventPtr *) xalloc (sizeof (ShapeEventPtr));
  647.         if (!pHead ||
  648.             !AddResource (pWin->drawable.id, EventType, (pointer)pHead))
  649.         {
  650.             FreeResource (clientResource, ClientType);
  651.             xfree (pHead);
  652.             xfree (pNewShapeEvent);
  653.             return BadAlloc;
  654.         }
  655.         *pHead = 0;
  656.         }
  657.         pNewShapeEvent->next = *pHead;
  658.         *pHead = pNewShapeEvent;
  659.     break;
  660.     case xFalse:
  661.     /* delete the interest */
  662.     if (pHead) {
  663.         pNewShapeEvent = 0;
  664.         for (pShapeEvent = *pHead; pShapeEvent; pShapeEvent = pShapeEvent->next) {
  665.         if (pShapeEvent->client == client)
  666.             break;
  667.         pNewShapeEvent = 0;
  668.         }
  669.         if (pShapeEvent) {
  670.         FreeResource (pShapeEvent->clientResource, ClientType);
  671.         if (pNewShapeEvent)
  672.             pNewShapeEvent->next = pShapeEvent->next;
  673.         else
  674.             *pHead = pShapeEvent->next;
  675.         xfree (pShapeEvent);
  676.         }
  677.     }
  678.     break;
  679.     default:
  680.     client->errorValue = stuff->enable;
  681.     return BadValue;
  682.     }
  683.     return Success;
  684. }
  685.  
  686. /*
  687.  * deliver the event
  688.  */
  689.  
  690. static void
  691. SendShapeNotify (pWin, which)
  692.     WindowPtr    pWin;
  693.     int        which;
  694. {
  695.     ShapeEventPtr    *pHead, pShapeEvent;
  696.     ClientPtr        client;
  697.     xShapeNotifyEvent    se;
  698.     BoxRec        extents;
  699.     RegionPtr        region;
  700.     BYTE        shaped;
  701.  
  702.     pHead = (ShapeEventPtr *) LookupIDByType(pWin->drawable.id, EventType);
  703.     if (!pHead)
  704.     return;
  705.     if (which == ShapeBounding) {
  706.     region = wBoundingShape(pWin);
  707.     if (region) {
  708.         extents = *(pWin->drawable.pScreen->RegionExtents) (region);
  709.         shaped = xTrue;
  710.     } else {
  711.         extents.x1 = -wBorderWidth (pWin);
  712.         extents.y1 = -wBorderWidth (pWin);
  713.         extents.x2 = pWin->drawable.width + wBorderWidth (pWin);
  714.         extents.y2 = pWin->drawable.height + wBorderWidth (pWin);
  715.         shaped = xFalse;
  716.     }
  717.     } else {
  718.     region = wClipShape(pWin);
  719.     if (region) {
  720.         extents = *(pWin->drawable.pScreen->RegionExtents) (region);
  721.         shaped = xTrue;
  722.     } else {
  723.         extents.x1 = 0;
  724.         extents.y1 = 0;
  725.         extents.x2 = pWin->drawable.width;
  726.         extents.y2 = pWin->drawable.height;
  727.         shaped = xFalse;
  728.     }
  729.     }
  730.     for (pShapeEvent = *pHead; pShapeEvent; pShapeEvent = pShapeEvent->next) {
  731.     client = pShapeEvent->client;
  732.     if (client == serverClient || client->clientGone)
  733.         continue;
  734.     se.type = ShapeNotify + ShapeEventBase;
  735.     se.kind = which;
  736.     se.window = pWin->drawable.id;
  737.     se.sequenceNumber = client->sequence;
  738.     se.x = extents.x1;
  739.     se.y = extents.y1;
  740.     se.width = extents.x2 - extents.x1;
  741.     se.height = extents.y2 - extents.y1;
  742.     se.time = currentTime.milliseconds;
  743.     se.shaped = shaped;
  744.     WriteEventsToClient (client, 1, (xEvent *) &se);
  745.     }
  746. }
  747.  
  748. static int
  749. ProcShapeInputSelected (client)
  750.     register ClientPtr    client;
  751. {
  752.     REQUEST(xShapeInputSelectedReq);
  753.     WindowPtr        pWin;
  754.     ShapeEventPtr    pShapeEvent, *pHead;
  755.     int            enabled;
  756.     xShapeInputSelectedReply    rep;
  757.     register int        n;
  758.  
  759.     REQUEST_SIZE_MATCH (xShapeSelectInputReq);
  760.     pWin = LookupWindow (stuff->window, client);
  761.     if (!pWin)
  762.     return BadWindow;
  763.     pHead = (ShapeEventPtr *) LookupIDByType(pWin->drawable.id, EventType);
  764.     enabled = xFalse;
  765.     if (pHead) {
  766.         for (pShapeEvent = *pHead;
  767.          pShapeEvent;
  768.          pShapeEvent = pShapeEvent->next)
  769.         {
  770.         if (pShapeEvent->client == client) {
  771.             enabled = xTrue;
  772.         break;
  773.         }
  774.         }
  775.     }
  776.     rep.type = X_Reply;
  777.     rep.length = 0;
  778.     rep.sequenceNumber = client->sequence;
  779.     rep.enabled = enabled;
  780.     if (client->swapped) {
  781.     swaps (&rep.sequenceNumber, n);
  782.     swapl (&rep.length, n);
  783.     }
  784.     WriteToClient (client, sizeof (xShapeInputSelectedReply), (char *) &rep);
  785.     return (client->noClientException);
  786. }
  787.  
  788. static int
  789. ProcShapeGetRectangles (client)
  790.     register ClientPtr    client;
  791. {
  792.     REQUEST(xShapeGetRectanglesReq);
  793.     WindowPtr            pWin;
  794.     xShapeGetRectanglesReply    rep;
  795.     xRectangle            *rects;
  796.     int                nrects, i;
  797.     RegionPtr            region;
  798.     register int        n;
  799.  
  800.     REQUEST_SIZE_MATCH(xShapeGetRectanglesReq);
  801.     pWin = LookupWindow (stuff->window, client);
  802.     if (!pWin)
  803.     return BadWindow;
  804.     switch (stuff->kind) {
  805.     case ShapeBounding:
  806.     region = wBoundingShape(pWin);
  807.     break;
  808.     case ShapeClip:
  809.     region = wClipShape(pWin);
  810.     break;
  811.     default:
  812.     client->errorValue = stuff->kind;
  813.     return BadValue;
  814.     }
  815.     if (!region) {
  816.     nrects = 1;
  817.     rects = (xRectangle *) ALLOCATE_LOCAL (sizeof (xRectangle));
  818.     if (!rects)
  819.         return BadAlloc;
  820.     switch (stuff->kind) {
  821.     case ShapeBounding:
  822.         rects->x = - (int) wBorderWidth (pWin);
  823.         rects->y = - (int) wBorderWidth (pWin);
  824.         rects->width = pWin->drawable.width + wBorderWidth (pWin);
  825.         rects->height = pWin->drawable.height + wBorderWidth (pWin);
  826.         break;
  827.     case ShapeClip:
  828.         rects->x = 0;
  829.         rects->y = 0;
  830.         rects->width = pWin->drawable.width;
  831.         rects->height = pWin->drawable.height;
  832.         break;
  833.     }
  834.     } else {
  835.     BoxPtr box;
  836.     nrects = REGION_NUM_RECTS(region);
  837.     box = REGION_RECTS(region);
  838.     rects = (xRectangle *) ALLOCATE_LOCAL (nrects * sizeof (xRectangle));
  839.     if (!rects && nrects)
  840.         return BadAlloc;
  841.     for (i = 0; i < nrects; i++, box++) {
  842.         rects[i].x = box->x1;
  843.         rects[i].y = box->y1;
  844.         rects[i].width = box->x2 - box->x1;
  845.         rects[i].height = box->y2 - box->y1;
  846.     }
  847.     DEALLOCATE_LOCAL (rects);
  848.     }
  849.     rep.type = X_Reply;
  850.     rep.sequenceNumber = client->sequence;
  851.     rep.length = (nrects * sizeof (xRectangle)) >> 2;
  852.     rep.ordering = YXBanded;
  853.     rep.nrects = nrects;
  854.     if (client->swapped) {
  855.     swaps (&rep.sequenceNumber, n);
  856.     swapl (&rep.length, n);
  857.     swapl (&rep.nrects, n);
  858.     SwapShorts ((short *)rects, (unsigned long)nrects * 4);
  859.     }
  860.     WriteToClient (client, sizeof (rep), (char *) &rep);
  861.     WriteToClient (client, nrects * sizeof (xRectangle), (char *) rects);
  862.     return client->noClientException;
  863. }
  864.  
  865. static int
  866. ProcShapeDispatch (client)
  867.     register ClientPtr    client;
  868. {
  869.     REQUEST(xReq);
  870.     switch (stuff->data) {
  871.     case X_ShapeQueryVersion:
  872.     return ProcShapeQueryVersion (client);
  873.     case X_ShapeRectangles:
  874.     return ProcShapeRectangles (client);
  875.     case X_ShapeMask:
  876.     return ProcShapeMask (client);
  877.     case X_ShapeCombine:
  878.     return ProcShapeCombine (client);
  879.     case X_ShapeOffset:
  880.     return ProcShapeOffset (client);
  881.     case X_ShapeQueryExtents:
  882.     return ProcShapeQueryExtents (client);
  883.     case X_ShapeSelectInput:
  884.     return ProcShapeSelectInput (client);
  885.     case X_ShapeInputSelected:
  886.     return ProcShapeInputSelected (client);
  887.     case X_ShapeGetRectangles:
  888.     return ProcShapeGetRectangles (client);
  889.     default:
  890.     return BadRequest;
  891.     }
  892. }
  893.  
  894. static void
  895. SShapeNotifyEvent(from, to)
  896.     xShapeNotifyEvent *from, *to;
  897. {
  898.     to->type = from->type;
  899.     to->kind = from->kind;
  900.     cpswapl (from->window, to->window);
  901.     cpswaps (from->sequenceNumber, to->sequenceNumber);
  902.     cpswaps (from->x, to->x);
  903.     cpswaps (from->y, to->y);
  904.     cpswaps (from->width, to->width);
  905.     cpswaps (from->height, to->height);
  906.     cpswapl (from->time, to->time);
  907.     to->shaped = from->shaped;
  908. }
  909.  
  910. static int
  911. SProcShapeQueryVersion (client)
  912.     register ClientPtr    client;
  913. {
  914.     register int    n;
  915.     REQUEST (xShapeQueryVersionReq);
  916.  
  917.     swaps (&stuff->length, n);
  918.     return ProcShapeQueryVersion (client);
  919. }
  920.  
  921. static int
  922. SProcShapeRectangles (client)
  923.     register ClientPtr    client;
  924. {
  925.     register char   n;
  926.     REQUEST (xShapeRectanglesReq);
  927.  
  928.     swaps (&stuff->length, n);
  929.     swapl (&stuff->dest, n);
  930.     swaps (&stuff->xOff, n);
  931.     swaps (&stuff->yOff, n);
  932.     SwapRestS(stuff);
  933.     return ProcShapeRectangles (client);
  934. }
  935.  
  936. static int
  937. SProcShapeMask (client)
  938.     register ClientPtr    client;
  939. {
  940.     register char   n;
  941.     REQUEST (xShapeMaskReq);
  942.  
  943.     swaps (&stuff->length, n);
  944.     swapl (&stuff->dest, n);
  945.     swaps (&stuff->xOff, n);
  946.     swaps (&stuff->yOff, n);
  947.     swapl (&stuff->src, n);
  948.     return ProcShapeMask (client);
  949. }
  950.  
  951. static int
  952. SProcShapeCombine (client)
  953.     register ClientPtr    client;
  954. {
  955.     register char   n;
  956.     REQUEST (xShapeCombineReq);
  957.  
  958.     swaps (&stuff->length, n);
  959.     swapl (&stuff->dest, n);
  960.     swaps (&stuff->xOff, n);
  961.     swaps (&stuff->yOff, n);
  962.     swapl (&stuff->src, n);
  963.     return ProcShapeCombine (client);
  964. }
  965.  
  966. static int
  967. SProcShapeOffset (client)
  968.     register ClientPtr    client;
  969. {
  970.     register char   n;
  971.     REQUEST (xShapeOffsetReq);
  972.  
  973.     swaps (&stuff->length, n);
  974.     swapl (&stuff->dest, n);
  975.     swaps (&stuff->xOff, n);
  976.     swaps (&stuff->yOff, n);
  977.     return ProcShapeOffset (client);
  978. }
  979.  
  980. static int
  981. SProcShapeQueryExtents (client)
  982.     register ClientPtr    client;
  983. {
  984.     register char   n;
  985.     REQUEST (xShapeQueryExtentsReq);
  986.  
  987.     swaps (&stuff->length, n);
  988.     swapl (&stuff->window, n);
  989.     return ProcShapeQueryExtents (client);
  990. }
  991.  
  992. static int
  993. SProcShapeSelectInput (client)
  994.     register ClientPtr    client;
  995. {
  996.     register char   n;
  997.     REQUEST (xShapeSelectInputReq);
  998.  
  999.     swaps (&stuff->length, n);
  1000.     swapl (&stuff->window, n);
  1001.     return ProcShapeSelectInput (client);
  1002. }
  1003.  
  1004. static int
  1005. SProcShapeInputSelected (client)
  1006.     register ClientPtr    client;
  1007. {
  1008.     register int    n;
  1009.     REQUEST (xShapeInputSelectedReq);
  1010.  
  1011.     swaps (&stuff->length, n);
  1012.     swapl (&stuff->window, n);
  1013.     return ProcShapeInputSelected (client);
  1014. }
  1015.  
  1016. static int
  1017. SProcShapeGetRectangles (client)
  1018.     register ClientPtr    client;
  1019. {
  1020.     REQUEST(xShapeGetRectanglesReq);
  1021.     register char   n;
  1022.  
  1023.     swaps (&stuff->length, n);
  1024.     swapl (&stuff->window, n);
  1025.     return ProcShapeGetRectangles (client);
  1026. }
  1027.  
  1028. static int
  1029. SProcShapeDispatch (client)
  1030.     register ClientPtr    client;
  1031. {
  1032.     REQUEST(xReq);
  1033.     switch (stuff->data) {
  1034.     case X_ShapeQueryVersion:
  1035.     return SProcShapeQueryVersion (client);
  1036.     case X_ShapeRectangles:
  1037.     return SProcShapeRectangles (client);
  1038.     case X_ShapeMask:
  1039.     return SProcShapeMask (client);
  1040.     case X_ShapeCombine:
  1041.     return SProcShapeCombine (client);
  1042.     case X_ShapeOffset:
  1043.     return SProcShapeOffset (client);
  1044.     case X_ShapeQueryExtents:
  1045.     return SProcShapeQueryExtents (client);
  1046.     case X_ShapeSelectInput:
  1047.     return SProcShapeSelectInput (client);
  1048.     case X_ShapeInputSelected:
  1049.     return SProcShapeInputSelected (client);
  1050.     case X_ShapeGetRectangles:
  1051.     return SProcShapeGetRectangles (client);
  1052.     default:
  1053.     return BadRequest;
  1054.     }
  1055. }
  1056. @
  1057.  
  1058.  
  1059. 1.1
  1060. log
  1061. @Initial revision
  1062. @
  1063. text
  1064. @d27 1
  1065. a27 1
  1066. /* $XConsortium: shape.c,v 5.10 89/12/13 15:26:57 keith Exp $ */
  1067. d118 1
  1068. a118 1
  1069.     if (xoff || yoff)
  1070. @
  1071.